<?php


namespace App\Resource\Service\Cart;


use App\Common\Constants\ErrorCode;
use App\Resource\Service\Goods\GoodsBaseService;
use Hyperf\Di\Annotation\Inject;

class CartBusinessService extends CartBaseService implements CartServiceInterface
{
    /**
     * @Inject()
     * @var GoodsBaseService
     */
    private $goodsBaseService;

    /**
     * 优惠后订单
     *
     * @param $discount
     * @param int $type
     * @return array
     * @author mengchenchen
     */
    public function afterDiscount($discount, $type = 1)
    {
        $result = $valetOrder = $this->getPresetOrder($type);

        $discountList = $this->splitDiscount($valetOrder['totalAmount'], $discount, $valetOrder['goodsList']);

        $func = function ($num1, $num2, $times = 0) use (&$func) {
            if (is_int($num1 / $num2) || $times >= 5) {
                return round($num1 / $num2 / pow(10, $times), $times);
            }
            $times++;
            return $func($num1 * 10, $num2, $times);
        };

        $result['goodsList'] = [];
        foreach ($valetOrder['goodsList'] as $goods) {
            $goods['reduced_amount'] = $discountList[$goods['id']];
            $goods['discount_amount'] = bcsub($goods['amount'], $discountList[$goods['id']], 2);
            $goods['reduced_price_selling'] = $func($discountList[$goods['id']], $goods['number']);
            $goods['discount_price_selling'] = bcsub($goods['price_selling'], $goods['reduced_price_selling'], 2);
            $result['goodsList'][] = $goods;
        }
        $result['totalAmount'] = bcsub($valetOrder['totalAmount'], $discount, 2);
        $result['totalAmount'] < 0 && $result['totalAmount'] = 0;

        return $this->success($result);
    }

    /**
     * 更新单个
     *
     * @param $goods_id
     * @param $number
     * @param int $type
     * @return array
     * @author mengchenchen
     */
    public function singleRefresh($goods_id, $number, $type = 1)
    {
        $user = $this->getCurrentInfo();
        if (!$goods = $this->getGoods($goods_id, $type)) {
            return $this->error(ErrorCode::NOT_EXIST, '不存在的商品id');
        }
        if ($number > $goods['number_stock']) {
            return $this->error(ErrorCode::GOODS_UNDER_STOCK, '选购数量过多，商品库存不足');
        }
        $goods['number'] = $number;
        if ($goods['number'] <= 0) {
            $this->redis->hDel("shop-cart:{$user['phone']}:$type", (string)$goods['id']);
        } else {
            $goods['time'] = time();

            $this->setPresetOrder($goods, $type);
        }

        $result = $this->getPresetOrder($type);
        $result['goodsList'] = array_values($result['goodsList']);

        return $this->success($result);
    }

    /**
     * 分割优惠券
     *
     * @param $total
     * @param $discount
     * @param $arr
     * @return array
     * @author mengchenchen
     */
    public function splitDiscount($total, $discount, $arr)
    {
        $result = [];
        end($arr);
        $end = key($arr);
        array_walk($arr, function ($v, $k) use ($total, $discount, $end, &$result) {
            $result[$k] = round(($k == $end) ? $discount - array_sum($result) : $v['price_selling'] * $v['number'] / $total * $discount, 2);
        });
        return $result;
    }

    /**
     * 获取商品选中数量
     *
     * @param $goods_id
     * @param int $type
     * @return int
     * @author mengchenchen
     */
    public function selectedGoodsNumber($goods_id, $type = 1)
    {
        $shop_account = $this->getCurrentInfo()['phone'];
        $goods = $this->redis->hGet("shop-cart:$shop_account:$type", "$goods_id");
        if (!$goods) {
            return 0;
        }
        return intval(unserialize($goods)['number'] ?? 0);
    }

    /**
     * 更新代客单
     *
     * @param $goods
     * @param int $type
     * @author mengchenchen
     */
    public function setPresetOrder($goods, $type = 1)
    {
        $shop_account = $this->getCurrentInfo()['phone'];
        $this->redis->hSet("shop-cart:$shop_account:$type", (string)$goods['id'], serialize($goods));
    }

    /**
     * 获取代客单
     *
     * @param int $type
     * @return array
     * @author mengchenchen
     */
    public function getPresetOrder($type = 1)
    {
        $shop_account = $this->getCurrentInfo()['phone'];

        $totalAmount = $goodsNumber = 0;

        $goodsList = [];
        foreach ($this->redis->hGetAll("shop-cart:$shop_account:$type") as $key => $value) {
            $value = unserialize($value);
            $goods = $this->getGoods($key, $type);
            if (!$goods || ($value['number'] > $goods['number_stock'])) {
                continue;
            }
            $goods['number'] = $value['number'];
            $goods['amount'] = bcmul($goods['number'], $goods['price_selling'], 2);
            $goods['time'] = $value['time'];
            $totalAmount = bcadd($totalAmount, $goods['amount'], 2);
            $goodsNumber += $value['number'] ?? 0;
            $goodsList[$key] = $goods;
        }

        return compact('goodsList', 'totalAmount', 'goodsNumber');
    }

    /**
     * 清空预设
     *
     * @param $type
     * @author mengchenchen
     */
    public function clearPreset($type)
    {
        $shop_account = $this->getCurrentInfo()['phone'];
        $this->redis->del("shop-cart:$shop_account:$type");
    }

    /**
     * 获取商品信息
     *
     * @param $goods_id
     * @param int $type
     * @return array
     * @author mengchenchen
     */
    public function getGoods($goods_id, $type = 1)
    {
        $goods = [];
        if ($type == 1) {
            $goods = $this->goodsBaseService->getResourceCommonTimelyArriveGoodsMsg($goods_id, $this->getCurrentInfo()['shop_id']);
        } elseif ($type == 2) {
            $goods = $this->goodsBaseService->getResourceCommonOverNightArriveGoodsMsg($goods_id);
        }
        return $goods;
    }

}